<?php 
class DataSourceMapper extends CFormModel{
    
    protected $_mapper;
    protected $_rules = array();
    protected $_attributes = array();
    protected $_method = array(
        'findByPk'              => 'findByPk',
        'findByAttributes'      => 'findByAttributes',
        'save'                  => 'save',
    );
    public    $importRules = true;
    public    $soruceName  = null;
    
    public function attributeNames(){
        return array_keys($this->_attributes);
    }
    
    public function rules(){
        return $this->_rules;
    }
    
    public function __get($name){
        $attributesMapper = $this->getAttributesMapper();
        if (array_key_exists($name,$attributesMapper)){
            return $this->getAttribute($name);
        }
        return parent::__get($name);
    }
    
    public function __set($name, $value){
        $attributesMapper = $this->getAttributesMapper();
        if (array_key_exists($name,$attributesMapper)){
            return $this->setAttribute($name,$value);
        }
        return parent::__set($name, $value);
    }
    
    public function setConfig($config){
        /**
         * build Mapper
         */
        if (array_key_exists('class', $config)){
            $className = Yii::import($config['class']);
        }else{
            $className = $this->soruceName;
        }
        $this->setMapper(new $className());
        
        if (array_key_exists('attributes', $config)){
            foreach ($config['attributes'] as $attribute){
                $this->_attributes[$attribute] = $this->soruceName.'.'.$attribute;
            }
            
            if ($this->importRules){
                $rules = $this->getMapper()->rules();
                
                foreach ($rules as $rule){
                    $ruleAttributes = explode(',', $rule[0]);
                    $daoRuleAttributes = array();                    
                    foreach ($ruleAttributes as $ruleAttribute){
                        $ruleAttribute = trim($ruleAttribute);
                        if (in_array($ruleAttribute,$this->attributeNames())){
                            array_push($daoRuleAttributes,$ruleAttribute);
                        }
                    }
                    $rule[0] = implode(',', $daoRuleAttributes);
                    array_push($this->_rules, $rule);
                }
                
            }
        }
        
        return $this;
    }
    
    public function setMapper($mapper){
        $this->_mapper = $mapper;
        return $this;
    }
    
    public function getMapper(){
        return $this->_mapper;
    }

    public function getAttribute($name){        
        return $this->getMapper()->$name;
    }
    
    public function setAttribute($name,$value){
        return $this->getMapper()->$name = $value;
    }
    
    public function getAttributesMapper(){
        return $this->_attributes;
    }   
    
    public function addRelation($source,$type,$config){
        $source->relationsConfig = $config;
        array_push($this->relations,$source);
        return $this;
    }
    
    public function findByPk($id){
        $methodName = $this->_method['findByPk']; 
        $result = $this->getMapper()->$methodName($id);
        if (!empty($result)){
            $this->setMapper($result);
            $this->attributes = $result->attributes;
        }
       
        return $this->attributes;
    }
    
    public function findByAttributes($attributes){
        $methodName = $this->_method['findByAttributes']; 
        $result = $this->getMapper()->$methodName($attributes);
        if (!empty($result)){
            $this->setMapper($result);
            $this->attributes = $result->attributes;
        }
        return $this->attributes;
    }
    
    public function save(){
        $methodName = $this->_method['save'];
        return $this->getMapper()->$methodName();
    }
    
    
    
}